from django.templatetags.i18n import register
from django.template.defaulttags import URLNode, url
from django.utils import translation
from django.conf import settings
from django.utils.encoding import smart_str


class LocURLNode(URLNode):
    def render(self, context):
        from django.core.urlresolvers import NoReverseMatch
        from urlresolvers import locreverse
        args = [arg.resolve(context) for arg in self.args]
        kwargs = dict(((smart_str(k,'ascii'), v.resolve(context))
                       for k, v in self.kwargs.iteritems()))
        
        # Try to look up the URL twice: once given the view name, and again
        # relative to what we guess is the "main" app. If they both fail,
        # re-raise the NoReverseMatch unless we're using the
        # {% url ... as var %} construct in which cause return nothing.
        url = ''
        try:
            url = locreverse(self.view_name, args=args, kwargs=kwargs, current_app=context.current_app)
        except NoReverseMatch, e:
            if settings.SETTINGS_MODULE:
                project_name = settings.SETTINGS_MODULE.split('.')[0]
                try:
                    url = locreverse(project_name + '.' + self.view_name,
                                     args=args, kwargs=kwargs, current_app=context.current_app)
                except NoReverseMatch:
                    if self.asvar is None:
                        # Re-raise the original exception, not the one with
                        # the path relative to the project. This makes a
                        # better error message.
                        raise e
            else:
                if self.asvar is None:
                    raise e

        if self.asvar:
            context[self.asvar] = url
            return ''
        else:
            return url
        
@register.tag
def locurl(parser, token):
    result = url(parser, token)
    result.__class__ = LocURLNode
    return result
